home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mint96sb.zoo / src / dossig.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-10  |  4.8 KB  |  212 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
  3. */
  4.  
  5. /* dossig.c:: dos signal handling routines */
  6.  
  7. #include "mint.h"
  8.  
  9. /*
  10.  * send a signal to another process. If pid > 0, send the signal just to
  11.  * that process. If pid < 0, send the signal to all processes whose process
  12.  * group is -pid. If pid == 0, send the signal to all processes with the
  13.  * same process group id.
  14.  *
  15.  * note: post_sig just posts the signal to the process.
  16.  */
  17.  
  18. long ARGS_ON_STACK
  19. p_kill(pid, sig)
  20.     int pid, sig;
  21. {
  22.     PROC *p;
  23.  
  24.     TRACE(("Pkill(%d, %d)", pid, sig));
  25.     if (sig < 0 || sig >= NSIG) {
  26.         DEBUG(("Pkill: signal out of range"));
  27.         return ERANGE;
  28.     }
  29.  
  30.     if (pid < 0)
  31.         return killgroup(-pid, sig);
  32.     else if (pid == 0)
  33.         return killgroup(curproc->pgrp, sig);
  34.     else {
  35.         p = pid2proc(pid);
  36.         if (p == 0 || p->wait_q == ZOMBIE_Q || p->wait_q == TSR_Q) {
  37.             DEBUG(("Pkill: pid %d not found", pid));
  38.             return EFILNF;
  39.         }
  40.         if (curproc->euid && curproc->ruid != p->ruid) {
  41.             DEBUG(("Pkill: wrong user"));
  42.             return EACCDN;
  43.         }
  44.  
  45. /* if the user sends signal 0, don't deliver it -- for users, signal
  46.  * 0 is a null signal used to test the existence of a process
  47.  */
  48.         if (sig != 0)
  49.             post_sig(p, sig);
  50.     }
  51.  
  52.     check_sigs();
  53.     TRACE(("Pkill: returning OK"));
  54.     return 0;
  55. }
  56.  
  57. /*
  58.  * set a user-specified signal handler, POSIX.1 style
  59.  * "oact", if non-null, gets the old signal handling
  60.  * behaviour; "act", if non-null, specifies new
  61.  * behaviour
  62.  */
  63.  
  64. long ARGS_ON_STACK
  65. p_sigaction(sig, act, oact)
  66.     int sig;
  67.     const struct sigaction *act;
  68.     struct sigaction *oact;
  69. {
  70.     TRACE(("Psigaction(%d)", sig));
  71.     if (sig < 1 || sig >= NSIG)
  72.         return ERANGE;
  73.     if (act && (sig == SIGKILL || sig == SIGSTOP))
  74.         return EACCDN;
  75.     if (oact) {
  76.         oact->sa_handler = curproc->sighandle[sig];
  77.         oact->sa_mask = curproc->sigextra[sig];
  78.         oact->sa_flags = curproc->sigflags[sig] & SAUSER;
  79.     }
  80.     if (act) {
  81.         ushort flags;
  82.  
  83.         curproc->sighandle[sig] = act->sa_handler;
  84.         curproc->sigextra[sig] = act->sa_mask & ~UNMASKABLE;
  85.  
  86. /* only the flags in SAUSER can be changed by the user */
  87.         flags = curproc->sigflags[sig] & ~SAUSER;
  88.         flags |= act->sa_flags & SAUSER;
  89.         curproc->sigflags[sig] = flags;
  90.  
  91. /* various special things that should happen */
  92.         if (act->sa_handler == SIG_IGN) {
  93.             /* discard pending signals */
  94.             curproc->sigpending &= ~(1L<<sig);
  95.         }
  96.  
  97. /* I dunno if this is right, but bash seems to expect it */
  98.          curproc->sigmask &= ~(1L<<sig);
  99.     }
  100.     return 0;
  101. }
  102.  
  103. /*
  104.  * set a user-specified signal handler
  105.  */
  106.  
  107. long ARGS_ON_STACK
  108. p_signal(sig, handler)
  109.     int sig;
  110.     long handler;
  111. {
  112.     long oldhandle;
  113.  
  114.     TRACE(("Psignal(%d, %lx)", sig, handler));
  115.     if (sig < 1 || sig >= NSIG)
  116.         return ERANGE;
  117.     if (sig == SIGKILL || sig == SIGSTOP)
  118.         return EACCDN;
  119.     oldhandle = curproc->sighandle[sig];
  120.     curproc->sighandle[sig] = handler;
  121.     curproc->sigextra[sig] = 0;
  122.     curproc->sigflags[sig] = 0;
  123.  
  124. /* various special things that should happen */
  125.     if (handler == SIG_IGN) {
  126.         /* discard pending signals */
  127.         curproc->sigpending &= ~(1L<<sig);
  128.     }
  129.  
  130. /* I dunno if this is right, but bash seems to expect it */
  131.     curproc->sigmask &= ~(1L<<sig);
  132.  
  133.     return oldhandle;
  134. }
  135.  
  136. /*
  137.  * block some signals. Returns the old signal mask.
  138.  */
  139.  
  140. long ARGS_ON_STACK
  141. p_sigblock(mask)
  142.     ulong mask;
  143. {
  144.     ulong oldmask;
  145.  
  146.     TRACE(("Psigblock(%lx)",mask));
  147. /* some signals (e.g. SIGKILL) can't be masked */
  148.     mask &= ~(UNMASKABLE);
  149.     oldmask = curproc->sigmask;
  150.     curproc->sigmask |= mask;
  151.     return oldmask;
  152. }
  153.  
  154. /*
  155.  * set the signals that we're blocking. Some signals (e.g. SIGKILL)
  156.  * can't be masked.
  157.  * Returns the old mask.
  158.  */
  159.  
  160. long ARGS_ON_STACK
  161. p_sigsetmask(mask)
  162.     ulong mask;
  163. {
  164.     ulong oldmask;
  165.  
  166.     TRACE(("Psigsetmask(%lx)",mask));
  167.     oldmask = curproc->sigmask;
  168.     curproc->sigmask = mask & ~(UNMASKABLE);
  169.     check_sigs();    /* maybe we unmasked something */
  170.     return oldmask;
  171. }
  172.  
  173. /*
  174.  * p_sigpending: return which signals are pending delivery
  175.  */
  176.  
  177. long ARGS_ON_STACK
  178. p_sigpending()
  179. {
  180.     TRACE(("Psigpending()"));
  181.     check_sigs();    /* clear out any that are going to be delivered soon */
  182.  
  183. /* note that signal #0 is used internally, so we don't tell the process
  184.  * about it
  185.  */
  186.     return curproc->sigpending & ~1L;
  187. }
  188.  
  189. /*
  190.  * p_sigpause: atomically set the signals that we're blocking, then pause.
  191.  * Some signals (e.g. SIGKILL) can't be masked.
  192.  */
  193.  
  194. long ARGS_ON_STACK
  195. p_sigpause(mask)
  196.     ulong mask;
  197. {
  198.     ulong oldmask;
  199.  
  200.     TRACE(("Psigpause(%lx)", mask));
  201.     oldmask = curproc->sigmask;
  202.     curproc->sigmask = mask & ~(UNMASKABLE);
  203.     if (curproc->sigpending & ~(curproc->sigmask))
  204.         check_sigs();    /* a signal is immediately pending */
  205.     else
  206.         sleep(IO_Q, -1L);
  207.     curproc->sigmask = oldmask;
  208.     check_sigs();    /* maybe we unmasked something */
  209.     TRACE(("Psigpause: returning OK"));
  210.     return 0;
  211. }
  212.